package cloud.health.framework.nat.proxy.domain;

import cloud.health.framework.computing.core.AbstractNettyClient;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

@Slf4j
public class Client extends AbstractNettyClient {

    private String host;
    private Integer port;
    private ChannelHandlerContext context;
    private ChannelHandlerContext proxy;

    public static Client build(ChannelHandlerContext context) {
        Client it = new Client();
        it.context = context;
        return it;
    }

    @Override
    protected String hostname() {
        return this.host;
    }

    @Override
    protected int port() {
        return this.port;
    }

    @Override
    protected ChannelInitializer<SocketChannel> channelInitializer() {
        return new ChannelInitializer<SocketChannel>() {

            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                log.info("ch = {}", ch);
                ch.pipeline().addLast(new CommandChannelHandler());
            }

        };
    }

    public ChannelHandlerContext getProxy() {
        return proxy;
    }

    public void run(String host, Integer port) {
        this.host = host;
        this.port = port;
        super.run();
    }

    class CommandChannelHandler extends ChannelInboundHandlerAdapter {

        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            proxy = ctx;
            log.info("channel is active, ctx = {}", ctx);
        }

        @Override
        public void channelInactive(ChannelHandlerContext ctx) {
            log.info("channel is inactive, ctx = {}", ctx);
            if (Objects.nonNull(context)) {
                context.close();
            }
            ctx.close();
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf buf = (ByteBuf) msg;
            try {
                String str = buf.toString(StandardCharsets.UTF_8);
                log.info("ctx = {}, size = {} , str = \n{}", ctx, buf.readableBytes(), str);
                if (Objects.nonNull(context)) {
                    context.writeAndFlush(buf.copy());
                }
                 else {
                     log.info("11!!!!!!");
                }
            } finally {
                buf.release();
            }
        }

    }

}
